from building import *
import json

for sc in Glob("*/SConscript"):
    SConscript(sc)

CWD = GetCurrentDir()

# generate(Glob("config/*/*.json"))
# generate(Glob("config/Dcm/excel/*.json"))

objsApp = Glob("*.c") + Glob("src/*.c")

LL_DL = os.getenv("LL_DL")


class ApplicationApp(Application):
    def config(self):
        self.CPPDEFINES = []
        self.CPPPATH = ["$INFRAS", "%s/include" % (CWD), CWD, "$Com_Cfg", "$EcuM_Cfg", "$StdTrace_Cfg"]
        self.LIBS = ["StdTimer", "EcuM"]
        for libName, source in self.libsForApp.items():
            self.LIBS.append(libName)
            self.RegisterConfig(libName, source)
            self.Append(CPPDEFINES=["USE_%s" % (libName.split(":")[0].upper())])
        self.source = objsApp


libsCommon = {
    "Dcm": Glob("config/Dcm/Dcm.json"),
    "Dem": Glob("config/Dcm/Dem.json"),
    "NvM": Glob("config/NvM/NvM.json"),
}

with open(Glob("config/NvM/NvM.json")[0].rstr()) as f:
    cfg = json.load(f)
    nvmTarget = os.getenv("NVM_TARGET", cfg.get("target", "Ea"))

if "Fee" == nvmTarget:
    libsCommon["Fls"] = Glob("config/NvM/Fls_Cfg.c")
if "Ea" == nvmTarget:
    libsCommon["Eep"] = Glob("config/NvM/Eep_Cfg.c")

libsForCanApp = {
    "OsekNm": Glob("config/Com/OsekNm.json"),
    "CanNm": Glob("config/Com/CanNm.json"),
    "CanSM": Glob("config/Com/CanSM.json"),
    "Com": Glob("config/Com/Com.json"),
    "ComM": Glob("config/Com/ComM.json"),
    "Nm": Glob("config/Com/Nm.json"),
    "CanTp": Glob("config/CanTp/CanTp.json"),
    "PduR": Glob("config/Com/PduR.json"),
    "CanIf": Glob("config/Com/CanIf.json"),
    "CanTSyn": Glob("config/CanTSyn/master/CanTSyn_Cfg.c"),
    "Xcp": Glob("config/Xcp/Xcp.json"),
    "StdTrace": Glob("config/Trace/Trace.json"),
    "Csm": Glob("config/Csm/Csm.json"),
    "SecOC": Glob("config/SecOC/SecOC.json"),
    "E2E": Glob("config/E2E/E2E.json"),
}
libsForCanApp.update(libsCommon)


@register_application
class ApplicationCanApp(ApplicationApp):
    def platform_config(self):
        self.Append(CPPDEFINES=["USE_STD_DEBUG", "USE_PLUGIN"])
        self.Append(CPPDEFINES=["FEE_USE_BLANK_CHECK", "FLS_ERASED_VALUE=0xFF"])
        self.Append(CPPDEFINES=["FLS_DIRECT_ACCESS"])
        # self.Append(CPPDEFINES=["FEE_PAGE_SIZE=256", "FEE_WORKING_AREA_SIZE=4096"])
        self.LIBS.append("Simulator")
        self.LIBS.append("Plugin")
        self.Append(CPPDEFINES=["USE_SHELL"])
        self.LIBS.append("Shell")
        self.LIBS.append("VFS")
        self.Append(CPPDEFINES=["USE_VFS"])
        self.LIBS.append("CryptoIf")
        self.Append(CPPDEFINES=["USE_CRYPTO"])
        # self.Append(CPPDEFINES=["USE_TRACE_APP"])
        self.LIBS += ["LibC"]
        # self.Append(CPPDEFINES=["USE_STD_PRINTF", "USE_STDIO_CAN", "USE_STDIO_CAN_FLUSH"])
        self.Append(CPPFLAGS=["-O0"])

    def config(self):
        if LL_DL != None:
            self.Append(CPPDEFINES=["CANTP_LL_DL=%s" % (LL_DL)])
        self.libsForApp = libsForCanApp
        super().config()
        self.Append(CPPDEFINES=["USE_CAN"])
        self.platform_config()
        self.Remove(CPPDEFINES="USE_OSEKNM")
        self.Remove(CPPDEFINES="USE_CANTSYN")


# generate(Glob("config/SWC/*/*.json"))
jsSwc = Glob("config/SWC/*/*.json")

objsSwc = Glob("config/SWC/*/*.c")


@register_application
class ApplicationCanIC(query_application("CanApp")):
    def config(self):
        self.Generate(jsSwc)
        super().config()
        self.Append(CPPDEFINES=["USE_VIC"])
        self.LIBS += ["VicServer"]
        self.source += objsSwc


@register_application
class ApplicationCanNm(ApplicationApp):
    def platform_config(self):
        self.Append(CPPDEFINES=["USE_STD_DEBUG"])
        self.LIBS.append("Simulator")

    def config(self):
        self.libsForApp = {k: libsForCanApp[k] for k in ["CanNm"]}
        super().config()
        self.Append(CPPDEFINES=["USE_CAN"])
        self.platform_config()


@register_application
class ApplicationOsekNm(ApplicationApp):
    def platform_config(self):
        self.Append(CPPDEFINES=["USE_STD_DEBUG"])
        self.LIBS.append("Simulator")

    def config(self):
        self.CPPPATH = ["$LinIf_Cfg"]
        self.libsForApp = {k: libsForCanApp[k] for k in ["OsekNm"]}
        super().config()
        self.Append(CPPDEFINES=["USE_CAN"])
        self.platform_config()


libsForLinApp = {
    "LinIf": Glob("../bootloader/config/LinIf/LinIf.json"),
    "LinTp": Glob("../bootloader/config/LinTp/LinTp.json"),
}
libsForLinApp.update(libsCommon)


@register_application
class ApplicationLinApp(ApplicationApp):
    def platform_config(self):
        self.Append(CPPDEFINES=["USE_STD_DEBUG"])
        self.LIBS += ["Simulator", "RingBuffer"]

    def config(self):
        if LL_DL != None:
            self.Append(CPPDEFINES=["LINTP_LL_DL=%s" % (LL_DL)])
        self.libsForApp = libsForLinApp
        super().config()
        self.CPPPATH += ["$LinIf_Cfg"]
        self.platform_config()


libsForNetApp = {
    "PduR": Glob("config/Net/PduR.json"),
    "CanTp": Glob("config/Net/CanTp.json"),
    "CanIf": Glob("config/Net/CanIf.json"),
    "UdpNm": Glob("config/Net/UdpNm_Cfg.c"),
}
libsForNetApp.update(libsCommon)


@register_application
class ApplicationNetApp(Application):
    mylibs = libsForNetApp

    def platform_config(self):
        self.Append(CPPDEFINES=["USE_STD_DEBUG", "USE_PLUGIN"])
        # self.Append(CPPDEFINES=['DISABLE_NET_MEM'])
        if LL_DL != None:
            self.Append(CPPDEFINES=["CANTP_LL_DL=%s" % (LL_DL)])
        self.Append(CPPDEFINES=["USE_CAN"])
        self.LIBS += ["Simulator", "Plugin"]

    def gencfg(self):
        source = self.Generate(["%s/config/Net/Network.json" % (CWD), "%s/config/Net/Mempool.json" % (CWD)])
        libs = {
            "SoAd": source["SoAd"] + source["MemCluster"],
            "DoIP": source["DoIP"],
            "Sd": source["Sd"],
            "SomeIp": source["SomeIp"]
            + source["SS_Exserver0Cpp"]
            + source["SS_server0Cpp"]
            + source["CS_client0Cpp"]
            + source["CS_Exclient0Cpp"],
        }
        self.mylibs.update(libs)

    def config(self):
        self.gencfg()
        self.CPPPATH = ["$INFRAS", "$EcuM_Cfg", "%s/include" % (CWD)]
        self.source = objsApp
        self.LIBS = ["TcpIp", "StdTimer", "EcuM"]
        self.Append(CPPDEFINES=["USE_TCPIP"])
        self.Append(CPPDEFINES=["DCM_DEFAULT_RXBUF_SIZE=4095", "DCM_DEFAULT_TXBUF_SIZE=4095"])
        self.platform_config()
        for libName, source in self.mylibs.items():
            self.LIBS.append(libName)
            self.RegisterConfig(libName, source)
            self.Append(CPPDEFINES=["USE_%s" % (libName.split(":")[0].upper())])

@register_application
class ApplicationNetAppT(query_application("NetApp")):
    mylibs = {}

    def gencfg(self):
        source = self.Generate(["%s/config/Net/Network.json" % (CWD), "%s/config/Net/Mempool.json" % (CWD)])
        libs = {
            "SoAd": source["SoAd_T"] + source["MemCluster"],
            "Sd": source["Sd_T"],
            "SomeIp": source["SomeIp_T"]
            + source["SS_Exclient0Cpp_T"]
            + source["SS_client0Cpp_T"]
            + source["CS_server0Cpp_T"]
            + source["CS_Exserver0Cpp_T"],
        }
        self.mylibs.update(libs)

    def config(self):
        super().config()
        self.Append(CPPDEFINES=["LWIP_IPADDR_CFG_NR=1"])
        self.Append(CPPPATH=["%s/config/Net/GEN" % (CWD)])
